﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ADIGRE.Infrastructure.Queries.Authentication;
using SharpArch.NHibernate.Contracts.Repositories;
using ADIGRE.Infrastructure.Queries.Pessoa;
using ADIGRE.Domain;
using System.Web.Security;
using SharpArch.NHibernate.Web.Mvc;
using ADIGRE.MVC3.Web.Controllers.ViewModels;
using ADIGRE.MVC3.Web.Util;

namespace ADIGRE.MVC3.Web.Controllers
{
    public class PessoaController : ControllerAuthorize
    {

        //
        // GET: /Pessoa/
        private readonly IAuthenticationService _authenticationService;
        private readonly INHibernateRepository<Pessoa> _PessoaRepository;
        private readonly INHibernateRepository<Usuario> _UsuarioRepository;
        private readonly IPessoaQuery _PessoaQueryRepository;


        public PessoaController(IAuthenticationService authenticationService, INHibernateRepository<Usuario> UsuarioRepository
            , INHibernateRepository<Pessoa> PessoaRepository, IPessoaQuery PessoaQueryRepository)
        {
            this._authenticationService = authenticationService;
            this._PessoaRepository = PessoaRepository;
            this._PessoaQueryRepository = PessoaQueryRepository;
            this._UsuarioRepository = UsuarioRepository;
        }

        public ActionResult Index()
        {
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.IsRoot = user.IsRoot;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                List<Pessoa> pessoas = _PessoaQueryRepository.GelAllPessoa().Where(x => x.NmPessoa != _Anonimo).ToList();
                return View(pessoas);
            }
            catch (Exception ex)
            {
                _ObjLog.Error("PessoaController(Index): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
                return RedirectToAction("Index", "Home");
            }
        }

        //
        // GET: /Pessoa/Details/5

        public ActionResult Details(int id)
        {
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.IsRoot = user.IsRoot;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                return View(this._PessoaRepository.Get(id));
            }
            catch (Exception ex)
            {
                _ObjLog.Error("PessoaController(Details): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return RedirectToAction("Index");
        }

        //
        // GET: /Pessoa/Create

        public ActionResult Create(int Id = 0)
        {
            Pessoa pessoa = new Pessoa();
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.IsRoot = user.IsRoot;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                if (!(user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador) || user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Tesoureiro)))
                    return RedirectToAction("Index", "Home");
                ViewBag.Perfis = new ComboListItem().ComboPerfisAcesso();

                if (Id > 0)
                    pessoa = this._PessoaRepository.Get(Id);
                if (pessoa.Usuario == null)
                    pessoa.Usuario = new Usuario();

            }
            catch (Exception ex)
            {
                _ObjLog.Error("PessoaController(Create): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
                return RedirectToAction("Index");
            }
            return View(pessoa);
        }

        //
        // POST: /Pessoa/Create

        [HttpPost, Transaction]
        public ActionResult Create(FormCollection collection)
        {
            Pessoa pessoa = new Pessoa();
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;

                ViewBag.IsRoot = user.IsRoot;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                if (!(user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador) || user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Tesoureiro)))
                    return RedirectToAction("Index", "Home");

                ViewBag.Perfis = new ComboListItem().ComboPerfisAcesso();

                TryUpdateModel(pessoa, collection);
                bool unchancedPass = false;
                if (pessoa.IsUsuario)
                {
                    if (unchancedPass = pessoa.Usuario.Id > 0 && string.IsNullOrWhiteSpace(pessoa.Usuario.NmSenha))
                        pessoa.Usuario.NmSenha = this._UsuarioRepository.Get(pessoa.Usuario.Id).NmSenha;
                    else if (string.IsNullOrWhiteSpace(pessoa.Usuario.NmSenha))
                        ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_EMPTY_SENHA);
                    if (string.IsNullOrWhiteSpace(pessoa.Usuario.NmLogin))
                        ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_EMPTY_USUARIO);
                    if (pessoa.Usuario.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Outro))
                        ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_PERFIL_EMPTY);
                    if (_UsuarioRepository.GetAll().Where(x => x.NmLogin == pessoa.Usuario.NmLogin.Trim() && x.Id != pessoa.Usuario.Id && !pessoa.Usuario.IsExcluido) != null)
                        ModelState.AddModelError("", GlobalResources.Sistema.Feedback.WARNING_USUARIO_EXISTS);
                }

                if (ModelState.IsValid)
                {

                    if ((!pessoa.IsUsuario && user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador)) || pessoa.Usuario.Id == 0)
                        pessoa.Usuario = null;
                    else if (user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador))
                    {
                        pessoa.Usuario.Validar(user);
                        if (!unchancedPass)
                            pessoa.Usuario.NmSenha = FormsAuthentication.HashPasswordForStoringInConfigFile(pessoa.Usuario.NmSenha, "SHA1");
                        if (pessoa.Usuario.Id > 0)
                        {
                            Usuario usuario = this._UsuarioRepository.Get(pessoa.Usuario.Id);
                            usuario.Complete(pessoa.Usuario);
                            pessoa.Usuario = usuario;
                        }
                        this._UsuarioRepository.SaveOrUpdate(pessoa.Usuario);
                    }
                    pessoa.Validar(user);
                    if (pessoa.Id > 0)
                    {
                        Pessoa person = this._PessoaRepository.Get(pessoa.Id);
                        if (!user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador))
                            pessoa.IsUsuario = person.IsUsuario;
                        person.Complete(pessoa);
                        pessoa = person;
                    }

                    this._PessoaRepository.SaveOrUpdate(pessoa);

                    if (pessoa.Usuario != null && pessoa.Usuario.Pessoa == null)
                    {
                        pessoa.Usuario.Pessoa = pessoa;
                        this._UsuarioRepository.Update(pessoa.Usuario);
                    }
                    _Feedback = GlobalResources.Sistema.Feedback.SUCCESS_CADASTRO;
                    return RedirectToAction("Index");
                }
                else
                {
                    ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_INVALID_DATA);
                }
            }
            catch (Exception ex)
            {
                _ObjLog.Error("PessoaController(Create[]): " + ex.ToString());
                ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_SYSTEM);
            }
            return View(pessoa);
        }

        //
        // GET: /Pessoa/Edit/5

        public ActionResult ChangePassword(int id = 0)
        {
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.IsRoot = user.IsRoot;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                return View(new ChangePasswordViewModel() { Id = id });
            }
            catch (Exception ex)
            {
                _ObjLog.Error("PessoaController(ChangePassword): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
                return RedirectToAction("Index");
            }
        }

        //
        // POST: /Pessoa/Edit/5

        [HttpPost, Transaction]
        public ActionResult ChangePassword(FormCollection collection)
        {
            try
            {
                var user = _authenticationService.GetUserAuthenticated();
                if (user.Pessoa != null)
                    ViewBag.UsuarioLogado = user.Pessoa.NmPessoa;
                else
                    ViewBag.UsuarioLogado = user.NmLogin;
                ViewBag.IsRoot = user.IsRoot;
                ViewBag.EnumPerfilAcesso = user.EnumPerfilAcesso;
                ChangePasswordViewModel change = new ChangePasswordViewModel();
                TryUpdateModel(change, collection);

                if (!user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador) || change.Id == 0)
                {
                    if (string.IsNullOrWhiteSpace(change.NmSenhaOld))
                        ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_EMPTY_SENHA);
                    else if (!user.NmSenha.Equals(FormsAuthentication.HashPasswordForStoringInConfigFile(change.NmSenhaOld, "SHA1")))
                        ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_INVALID_SENHA);
                }
                if (string.IsNullOrWhiteSpace(change.NmSenha) || string.IsNullOrWhiteSpace(change.NmSenhaConfirm))
                    ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_EMPTY_SENHA);
                else if (!change.NmSenha.Equals(change.NmSenhaConfirm))
                    ModelState.AddModelError("", GlobalResources.Sistema.Feedback.ERROR_DIVERGENT_SENHA);
                if (ModelState.IsValid)
                {
                    if (change.Id > 0 && user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador))
                    {
                        Usuario usuario = this._UsuarioRepository.Get(change.Id);
                        usuario.NmSenha = FormsAuthentication.HashPasswordForStoringInConfigFile(change.NmSenha, "SHA1");
                        usuario.Validar(user);
                        this._UsuarioRepository.Update(usuario);

                    }
                    else if (change.Id == 0)
                    {
                        user.NmSenha = FormsAuthentication.HashPasswordForStoringInConfigFile(change.NmSenha, "SHA1");
                        user.Validar(user);
                        this._UsuarioRepository.Update(user);
                    }
                    _Feedback = GlobalResources.Sistema.Feedback.SUCCESS_SENHA;
                    return RedirectToAction("Index");
                }
                else
                    return View(new ChangePasswordViewModel() { Id = change.Id });

            }
            catch (Exception ex)
            {
                _ObjLog.Error("PessoaController(ChangePassword[]): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return RedirectToAction("Index", "Home");
        }

        //
        // GET: /Pessoa/Delete/5
        [Transaction]
        public ActionResult Delete(int id)
        {
            try
            {
                var user = this._authenticationService.GetUserAuthenticated();
                Pessoa pessoa = this._PessoaRepository.Get(id);
                if (pessoa != null && !pessoa.IsUsuario &&
                    (user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Administrador) || user.EnumPerfilAcesso.Equals(EnumPerfilAcesso.Tesoureiro)))
                {
                    pessoa.ValidarExclusao(user);
                    this._PessoaRepository.SaveOrUpdate(pessoa);
                    _Feedback = GlobalResources.Sistema.Feedback.SUCCESS_DELETE;
                }
            }
            catch (Exception ex)
            {
                _ObjLog.Error("PessoaController(Delete): " + ex.ToString());
                _Feedback = GlobalResources.Sistema.Feedback.ERROR_SYSTEM;
            }
            return RedirectToAction("Index");
        }

    }
}
